

#include "server-interface.h"
#include "../base/message-server-client.h"

ServerInterface::ServerInterface(QWidget *parent)
    : QDialog(parent) {
    portLabel = new QLabel(tr("Listening on port for clients:"));
    portLineEdit = new QLineEdit("12345");
    portLineEdit->setValidator(new QIntValidator(1, 65535, this));

    sendAddressLabel = new QLabel(tr("Send To Address:"));
    sendAddressLineEdit = new QLineEdit("127.0.0.1");

    portSendLabel = new QLabel(tr("Send port:"));
    portSendLineEdit = new QLineEdit();
    portSendLineEdit->setValidator(new QIntValidator(1, 65535, this));

    statusLabel = new QLabel(tr(""));//dxx

    startButton = new QPushButton(tr("&Send datagram"));
    startButton->setEnabled(false);
    quitButton = new QPushButton(tr("&Quit"));
    bindButton = new QPushButton(tr("&Bind"));

    buttonBox = new QDialogButtonBox;
    buttonBox->addButton(startButton, QDialogButtonBox::ActionRole);
    buttonBox->addButton(bindButton, QDialogButtonBox::ActionRole);
    buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);

    timer = new QTimer(this);

    message_ = new Message(messages::ACK_LOGIN);

    connect(portLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(enable_bind_button()));
    connect(sendAddressLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(enable_send_button()));
    connect(portSendLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(enable_send_button()));

    connect(startButton, SIGNAL(clicked()), this, SLOT(send_message()));
    connect(bindButton, SIGNAL(clicked()), this, SLOT(create_recv_socket()));

    connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));

    connect(&server_to_client_thread_, SIGNAL(message_received()), this, SLOT(process_pending_messages()));
    //connect(timer, SIGNAL(timeout()), this, SLOT(send_message()));

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(sendAddressLabel);
    mainLayout->addWidget(sendAddressLineEdit);
    mainLayout->addWidget(portSendLabel);
    mainLayout->addWidget(portSendLineEdit);
    mainLayout->addWidget(portLabel);
    mainLayout->addWidget(portLineEdit);
    mainLayout->addWidget(statusLabel);
    mainLayout->addWidget(buttonBox);
    setLayout(mainLayout);

    setWindowTitle(tr("Serverul TADA"));

    LOG(INFO) << "Am creat interfata";
}

void ServerInterface::enable_send_button() {
    startButton->setEnabled(!sendAddressLineEdit->text().isEmpty()
            && !portSendLineEdit->text().isEmpty());
}

void ServerInterface::send_message() {
    server_to_client_thread_.send_message(
            QHostAddress(sendAddressLineEdit->text()).toIPv4Address(),
            portSendLineEdit->text().toInt(),
            message_);
}


void ServerInterface::enable_bind_button() {
    bindButton->setEnabled(!portLineEdit->text().isEmpty());
}

void ServerInterface::create_recv_socket() {
    bindButton->setEnabled(false);
    server_to_client_thread_.create_recv_socket(portLineEdit->text().toInt());
}

void ServerInterface::process_pending_messages() {
    LOG(INFO) << "mesaj nou de prelucrat";

    const Message* message = NULL;
    quint32 address;

    server_to_client_thread_.head_message(&message, &address);
    server_to_client_thread_.dequeue_message();

    if (message == NULL) {
        LOG(INFO) << "mesajul e null";
        return;
    }

    LOG(INFO) << "noul mesaj e de tip " << message->type();

    switch ( message->type() )
    {
        case messages::LOGIN:
            process_login_message(message, address);
        break;
        case messages::S_LIST_SEGMENT:
        break;
        case messages::S_LIST_FINISH:
        break;
        case messages::S_QUERY:
            send_query_result();
        break;
        case messages::LOGOUT:
        break;
    }
}

void ServerInterface::process_login_message(const Message* message, quint32 address)
{
    LOG(INFO) << "procesam mesajul de login primit";
    Message* mess = new Message(messages::ACK_LOGIN);
    LOG(INFO) << "adaugam clientul in lista de clienti";
    clients_list_.add_client(message);
    LOG(INFO) << "extragem portul";
    quint16 port = ((messages::Login*)message)->port();
    LOG(INFO) << "construim adresa";
    LOG(INFO) << "trimitem mesajul de ack login la adresa: ";
    LOG(INFO) << " portul " << port;
    server_to_client_thread_.send_message(address, port, mess);
}

void ServerInterface::send_query_result()
{
    // TODO trebuie intors de search
}